package com.yc.tomcat.core;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;

import com.yc.tomcat.utils.StringUtil;

public class HttpServletResponse implements ServletResponse{
	private OutputStream os;
	private String projectName;

	public HttpServletResponse(String projectName, OutputStream os) {
		this.os = os;
		this.projectName = projectName;
	}

	@Override
	public PrintWriter getWriter() throws IOException {
		String responseHeader = "HTTP/1.1 200 OK\r\nContent-Type:application/json\r\n";
		if (!StringUtil.checkNull(ServerService.jsessionId)) {
			responseHeader += "Set-Cookie:" + ContantInfo.REQUEST_JSESSIONID + "=" + ServerService.jsessionId + "\r\n";
			ServerService.jsessionId = null;
		}
		responseHeader += "\r\n";
		os.write(responseHeader.getBytes());
		os.flush();
		return new PrintWriter(os);
	}

	@Override
	public void sendRedirect(String url) {
		if (StringUtil.checkNull(url) || "/".equals(url)) {
			send302("/login/");
			return;
		}
		
		if (!url.startsWith(projectName)) {  // 说明可能是servlet中的重定向
			url = projectName + "/" + url;
			url = url.replace("/+", "/");  // 将// 变成  /
			send302(url);
//			System.out.println("url1" + "--" + url);
			return;
		}
		
		if (url.startsWith("/") && url.indexOf("/") == url.lastIndexOf("/")) {
//			System.out.println("url2" + "--" + url);
			send302(url + "/");
			return;
		}
		
		if (url.endsWith("/")) {  // 说明没有指定具体的访问资源
			url += ContantInfo.DEFAULT_RESOURCE;
		}
//		System.out.println(url);
		// 读取用户指定的文件
		File fl = new File(ContantInfo.BASE_PATH, url.substring(1).replace("/", "\\"));
		if (!fl.exists() || !fl.isFile()) {
			error404(url);  // 如果资源不存在则报错404
			return;
		}
		send200(fl, url.substring(url.lastIndexOf(".") + 1).toLowerCase());
	}

	private void send302(String url) {
		String responseHeader = "HTTP/1.1 302 Moved Temporaily\r\nContent-Type:text/html;charset=utf-8\r\n";
		responseHeader += "Location:" + url + "\r\n\r\n";
		System.out.println(responseHeader);
		sendInfo(responseHeader);
	}

	private void send200(File fl, String extension) {
		String contentType = "text/html;charset=utf-8";
		String type = ParseWebXml.getContentType(extension);
		if (!StringUtil.checkNull(type)) {
			contentType = type;
		}
		byte[] bt = readFile(fl);
		//System.out.println("contentType  " + contentType);
		String responseHeader = "HTTP/1.1 200 OK\r\nContent-Type:" + contentType + "\r\nContent-Length:" + bt.length + "\r\n";
		if (!StringUtil.checkNull(ServerService.jsessionId)) {
			responseHeader += "Set-Cookie:" + ContantInfo.REQUEST_JSESSIONID + "=" + ServerService.jsessionId + "\r\n";
			ServerService.jsessionId = null;
		}
		responseHeader += "\r\n";
		sendInfo(responseHeader, bt);
	}

	private void sendInfo(String responseHeader, byte[] bt) {
		try {
			os.write(responseHeader.getBytes());
			os.write(bt);
			os.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private byte[] readFile(File fl) {
		byte[] bt = null;
		try (FileInputStream fis = new FileInputStream(fl)){
			bt = new byte[fis.available()];
			fis.read(bt);
		}catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		}
		return bt;
	}

	private void error404(String url) {
		String data = "<h1>HTTP Status 404 - " + url + "</h1>";
		String responseHeader = "HTTP/1.1 404 File Not Found\r\nContent-type:text/html;charset=utf-8\r\n";
		responseHeader += "Content-Length:" + data.getBytes().length + "\r\n\r\n" + data;
		sendInfo(responseHeader);
		
	}

	private void sendInfo(String responseHeader) {
		try {
			os.write(responseHeader.getBytes());
			os.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
